#ifndef __M_LOG_H__
#define __M_LOG_H__
#include <iostream>
#include <ctime>

#define DBG_LEVEL 0
#define INF_LEVEL 1
#define ERR_LEVEL 2
#define DEFAULT_LEVEL DBG_LEVEL
#define LOG(lev_str, level, format, ...) {\
    if (level >= DEFAULT_LEVEL) {\
        time_t t = time(nullptr);\
        struct tm* ptm = localtime(&t);\
        char time_str[32];\
        strftime(time_str, 31, "%H:%M:%S", ptm);\
        printf("[%s][%s][%s:%d]\t" format "\n", lev_str, time_str, __FILE__, __LINE__, ##__VA_ARGS__);\
    }\
}

#define DLOG(format, ...) LOG("DBG", DBG_LEVEL, format, ##__VA_ARGS__)
#define ILOG(format, ...) LOG("INF", INF_LEVEL, format, ##__VA_ARGS__)
#define ELOG(format, ...) LOG("ERR", ERR_LEVEL, format, ##__VA_ARGS__)
#endif

//... 捕获了 format 之后的所有参数，这些参数将作为 __VA_ARGS__ 传递给 LOG 宏。
//##__VA_ARGS__ 是一个GNU C扩展，用于在宏展开时处理空的可变参数列表。如果 format 后面没有跟随任何参数，
//它将确保 printf 调用中不会出现多余的逗号。然而，在这个特定的宏定义中，由于 format 后面至少应该有一个参数
//（否则格式化字符串就没有意义了），所以 ## 可能是可选的，但保留它可以提高代码的健壮性和兼容性。